package lumis.service.doui.propertybag;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.w3c.dom.Node;

import lumis.doui.processaction.ProcessActionContainer;
import lumis.doui.table.TableSource;
import lumis.doui.table.TableUpdateMultiRowDataProcessActionHandler;
import lumis.portal.PortalException;
import lumis.portal.UnexpectedException;
import lumis.portal.authentication.SessionConfig;
import lumis.portal.manager.ManagerFactory;
import lumis.portal.propertybag.PropertyBag;
import lumis.util.IResource;
import lumis.util.ITransaction;
import lumis.util.TextUtil;
import lumis.util.XmlUtil;

/**
 * Update process action handler for property bag.
 *
 * @version $Revision: 10825 $ $Date: 2009-08-04 12:36:40 -0300 (Tue, 04 Aug 2009) $
 * @since 5.0.0
 */
public class PropertyBagProcessActionHandler extends TableUpdateMultiRowDataProcessActionHandler
{
	private PropertyBag propertyBag = null;
	private Set<String> addedProperties = new HashSet<String>();
	private IResource resource = null;
	
	@Override
	public void init(Node processActionNode, ProcessActionContainer processActionContainer) throws PortalException
	{
		super.init(processActionNode, processActionContainer);
		propertyBag = getPropertyBag(sessionConfig, source, transaction);
	}
	
	@Override
	protected IResource getResource() throws PortalException
	{
		if(resource == null)
		{
			resource = super.getResource();
			resource.addResourcePath("lumis/service/doui/propertybag/strings/strings");
		}
		
		return resource;
	}
	
	@Override
	protected void addRow() throws PortalException
	{
		addOrUpdateValues();
	}


	@Override
	protected void updateRow() throws PortalException
	{
		addOrUpdateValues();
	}
	
	@Override
	protected void deleteRows(String primaryKeyFieldId, Collection<String> rowsDeleted) throws PortalException
	{
		for(String rowToDelete: rowsDeleted)
		{
			propertyBag.removeProperty(rowToDelete);
		}
		ManagerFactory.getEntityManager().flush();
	}
	
	/**
	 * Add or update the property for the current row.
	 * @since 5.0.0
	 */
	private void addOrUpdateValues() throws PortalException
	{
		String propertyName = getParameter("name", String.class);
		if(!addedProperties.add(propertyName))
			throw new PortalException("STR_DUPLICATED_PROPERTY_NAME;" + TextUtil.escapeLocalizationParameter(propertyName), getResource());
		
		// generate the property values list
		String values = getParameter("values", String.class);
		List<String> listValues = new ArrayList<String>();
		if(values != null)
		{
			String[] arrayValue = values.split("\n");
			for(String value: arrayValue)
			{
				listValues.add(value);
			}
		}
		
		// remove the property if it has been renamed
		String propertyId = getParameter("id", String.class);
		if(propertyId != null && !propertyId.equals(propertyName))
		{
			propertyBag.removeProperty(propertyId);
			ManagerFactory.getEntityManager().flush();
		}

		// set the property values
		propertyBag.setDefaultValues(propertyName, listValues);
	}
	
	/**
	 * Returns the property bag for an item being added or edited.
	 * @param sessionConfig user session information.
	 * @param source the source of the item being added or edited.
	 * @param transaction the transaction for persistence access.
	 * @since 5.0.0
	 */
	private PropertyBag getPropertyBag(SessionConfig sessionConfig, TableSource source, ITransaction transaction) throws PortalException
	{
		String propertyBagId = getParameter("propertyBagId", String.class);
		if(propertyBagId == null)
		{
			Node sourceNode = source.getDefinitionNode();
			String propertyBagSourceId = XmlUtil.readNodeString("propertyBagSourceId", sourceNode);
			String propertyBagFieldId = XmlUtil.readNodeString("propertyBagFieldId", sourceNode);
			TableSource propertyBagSource = (TableSource)source.getSourceContainer().getSourceById(propertyBagSourceId);
			String PBSourcePKId = propertyBagSource.getPrimaryKeyField().getId();
			String pKValue = (String)propertyBagSource.getParameterValue(PBSourcePKId);
			if(pKValue != null)
				propertyBagId = propertyBagSource.readData(pKValue, transaction).get(propertyBagFieldId, String.class);
		}
		
		if(propertyBagId != null)
			propertyBag = ManagerFactory.getPropertyBagManager().get(propertyBagId);
		
		if(propertyBag == null)
			throw new UnexpectedException("Property bag not found");
		
		return propertyBag;
	}
}
